-
Notifications
You must be signed in to change notification settings - Fork 4k
tools: Prevent invalid mem access when reading PAGE_OFFSET on s390 #5434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| #else | ||
| page_offset = __PAGE_OFFSET_BASE_L4; | ||
| #endif | ||
| #elif defined(__identity_base) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about #elif defined(CONFIG_S390) && defined(__identity_base) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently __identity_base is only defined on s390 so they're equivalent.
I remember hesitating between the two and my reason to chose the former is that if __identity_base is ever defined on an other arch, it would most likely be for the same purpose.
On the other hand, PAGE_OFFSET seems to be very arch specific and I don't how likely my scenario is likely to happen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, Thank you.
tools/profile.py
Outdated
| #endif | ||
| #elif defined(__identity_base) | ||
| // s390 6.10 and later PAGE_OFFSET is not a constant and need | ||
| // to be read from the kernel adress space |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
address, please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fix.
Since kernel 6.10, PAGE_OFFSET on s390 is not a constant anymore but
points to vm.identity_base and needs to be dereferenced properly with
bpf_probe_read_kernel().
Fixes the following error:
bpf: Failed to load program: Permission denied
0: R1=ctx() R10=fp0
; int trace_0(struct pt_regs *ctx) { @ main.c:172
0: (bf) r6 = r1 ; R1=ctx() R6_w=ctx()
; u64 tgid_pid = bpf_get_current_pid_tgid(); @ main.c:68
1: (85) call bpf_get_current_pid_tgid#14 ; R0_w=scalar()
2: (7b) *(u64 *)(r10 -8) = r0 ; R0_w=scalar(id=1) R10=fp0 fp-8_w=scalar(id=1)
3: (b7) r7 = 0 ; R7_w=0
; struct entry_t entry = {}; @ main.c:75
4: (7b) *(u64 *)(r10 -16) = r7 ; R7_w=0 R10=fp0 fp-16_w=0
5: (7b) *(u64 *)(r10 -24) = r7 ; R7_w=0 R10=fp0 fp-24_w=0
; entry.start_ns = bpf_ktime_get_ns(); @ main.c:76
6: (85) call bpf_ktime_get_ns#5 ; R0=scalar()
7: (7b) *(u64 *)(r10 -32) = r0 ; R0=scalar(id=2) R10=fp0 fp-32_w=scalar(id=2)
; entry.id = id; @ main.c:77
8: (7b) *(u64 *)(r10 -40) = r7 ; R7=0 R10=fp0 fp-40_w=0
; entry.kernel_stack_id = bcc_get_stackid(bpf_pseudo_fd(1, -3), ctx, 0); @ main.c:94
9: (18) r2 = 0xfd038000 ; R2_w=map_ptr(map=stacks,ks=4,vs=1016)
; return bcc_get_stackid_(ctx, (void *)map, flags); @ helpers.h:660
11: (bf) r1 = r6 ; R1_w=ctx() R6=ctx()
12: (b7) r3 = 0 ; R3_w=0
13: (85) call bpf_get_stackid#27 ; R0_w=scalar()
; entry.kernel_stack_id = bcc_get_stackid(bpf_pseudo_fd(1, -3), ctx, 0); @ main.c:94
14: (63) *(u32 *)(r10 -24) = r0 ; R0_w=scalar() R10=fp0 fp-24=mmmmscalar()
; if (entry.kernel_stack_id >= 0) { @ main.c:96
15: (6d) if r7 s> r0 goto pc+6 ; R0_w=scalar(smin=0,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff)) R7=0
; u64 ip = PT_REGS_IP(ctx); @ main.c:97
16: (79) r1 = *(u64 *)(r6 +16) ; R1_w=scalar() R6=ctx()
; page_offset = PAGE_OFFSET; @ main.c:114
17: (18) r2 = 0x0 ; R2_w=0
19: (79) r2 = *(u64 *)(r2 +16)
R2 invalid mem access 'scalar'
processed 18 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 1
Traceback (most recent call last):
File "/usr/share/bcc/tools/funcslower", line 266, in <module>
b.attach_kprobe(event=function, fn_name="trace_%d" % i)
File "/usr/lib/python3.12/site-packages/bcc/__init__.py", line 877, in attach_kprobe
fn = self.load_func(fn_name, BPF.KPROBE)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/bcc/__init__.py", line 552, in load_func
raise Exception("Failed to load BPF program %s: %s" %
Exception: Failed to load BPF program b'trace_0': Permission denied
Signed-off-by: Jerome Marchand <[email protected]>
c147153 to
8105da1
Compare
ekyooo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you.
Since kernel 6.10, PAGE_OFFSET on s390 is not a constant anymore but points to vm.identity_base and needs to be dereferenced properly with bpf_probe_read_kernel().
Fixes the following error:
bpf: Failed to load program: Permission denied
0: R1=ctx() R10=fp0
; int trace_0(struct pt_regs *ctx) { @ main.c:172
0: (bf) r6 = r1 ; R1=ctx() R6_w=ctx()
; u64 tgid_pid = bpf_get_current_pid_tgid(); @ main.c:68
1: (85) call bpf_get_current_pid_tgid#14 ; R0_w=scalar()
2: (7b) *(u64 *)(r10 -8) = r0 ; R0_w=scalar(id=1) R10=fp0 fp-8_w=scalar(id=1)
3: (b7) r7 = 0 ; R7_w=0
; struct entry_t entry = {}; @ main.c:75
4: (7b) *(u64 *)(r10 -16) = r7 ; R7_w=0 R10=fp0 fp-16_w=0
5: (7b) *(u64 *)(r10 -24) = r7 ; R7_w=0 R10=fp0 fp-24_w=0
; entry.start_ns = bpf_ktime_get_ns(); @ main.c:76
6: (85) call bpf_ktime_get_ns#5 ; R0=scalar()
7: (7b) *(u64 *)(r10 -32) = r0 ; R0=scalar(id=2) R10=fp0 fp-32_w=scalar(id=2)
; entry.id = id; @ main.c:77
8: (7b) *(u64 *)(r10 -40) = r7 ; R7=0 R10=fp0 fp-40_w=0
; entry.kernel_stack_id = bcc_get_stackid(bpf_pseudo_fd(1, -3), ctx, 0); @ main.c:94
9: (18) r2 = 0xfd038000 ; R2_w=map_ptr(map=stacks,ks=4,vs=1016)
; return bcc_get_stackid_(ctx, (void *)map, flags); @ helpers.h:660
11: (bf) r1 = r6 ; R1_w=ctx() R6=ctx()
12: (b7) r3 = 0 ; R3_w=0
13: (85) call bpf_get_stackid#27 ; R0_w=scalar()
; entry.kernel_stack_id = bcc_get_stackid(bpf_pseudo_fd(1, -3), ctx, 0); @ main.c:94
14: (63) *(u32 *)(r10 -24) = r0 ; R0_w=scalar() R10=fp0 fp-24=mmmmscalar()
; if (entry.kernel_stack_id >= 0) { @ main.c:96
15: (6d) if r7 s> r0 goto pc+6 ; R0_w=scalar(smin=0,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff)) R7=0
; u64 ip = PT_REGS_IP(ctx); @ main.c:97
16: (79) r1 = *(u64 *)(r6 +16) ; R1_w=scalar() R6=ctx()
; page_offset = PAGE_OFFSET; @ main.c:114
17: (18) r2 = 0x0 ; R2_w=0
19: (79) r2 = *(u64 *)(r2 +16)
R2 invalid mem access 'scalar'
processed 18 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 1
Traceback (most recent call last):
File "/usr/share/bcc/tools/funcslower", line 266, in
b.attach_kprobe(event=function, fn_name="trace_%d" % i)
File "/usr/lib/python3.12/site-packages/bcc/init.py", line 877, in attach_kprobe
fn = self.load_func(fn_name, BPF.KPROBE)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/bcc/init.py", line 552, in load_func
raise Exception("Failed to load BPF program %s: %s" %
Exception: Failed to load BPF program b'trace_0': Permission denied